package com.theanh.RssActivity.ui;

import java.util.ArrayList;
import java.util.List;

import com.theanh.RssActivity.R;
import com.theanh.RssActivity.Store;
import com.theanh.RssActivity.db.DbAdapter;
import com.theanh.RssActivity.entity.Category;
import com.theanh.RssActivity.entity.Channel;
import com.theanh.RssActivity.entity.Item;
import com.theanh.RssActivity.ui.adapter.ChannelAdapter;
import com.theanh.RssActivity.ui.adapter.ItemAdapter;
import com.theanh.RssActivity.ui.model.ChannelModel;
import com.theanh.RssActivity.ui.model.ItemModel;
import com.theanh.RssActivity.updater.ChannelUpdater;
import com.theanh.RssActivity.util.Constants;
import com.theanh.RssActivity.util.DbUtils;
import com.theanh.RssActivity.util.DialogUtils;
import com.theanh.RssActivity.util.FileUtils;
import com.theanh.RssActivity.util.RssUtils;
import com.theanh.RssActivity.util.Utils;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.database.SQLException;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class ListChannelScreen extends ListActivity {
	public static final String TAG = "ListChannelScreen";
	private static final int UPDATE_CHANNEL_MESSAGE = 2;
	private static final int ADD_CHANNEL = Menu.FIRST;
	private static final int EDIT_CHANNEL = Menu.FIRST + 1;
	private static final int DELETE_CHANNEL = Menu.FIRST + 2;
	private static final int UPDATE_CHANNEL = Menu.FIRST + 3;
	public Category category;
	private ChannelAdapter adapter;

	private MenuItem mnuAddChannel;
	private MenuItem mnuDeleteChannel;
	private MenuItem mnuEditChannel;
	private MenuItem mnuUpdateChannel;

	private int positionFocusChannel = 0;
	List<Channel> channels = new ArrayList<Channel>();
	private List<ChannelUpdater> updaters = new ArrayList<ChannelUpdater>();
	
	private Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case UPDATE_CHANNEL_MESSAGE:
				if (adapter != null)
					adapter.channels = channels;
				setProgressBarIndeterminateVisibility(false);
				Log.i(TAG, "invalidateViews");
				// setListAdapter(adapter);
				getListView().invalidateViews();
				break;
			}
			super.handleMessage(msg);
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);

		// Set category
		this.category = Store.categoryModelSelected.category;

		this.setTitle(category.getName());

		Window w = getWindow();

		// Request for the progress bar to be shown in the title
		w.requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

		w.requestFeature(Window.FEATURE_LEFT_ICON);

		setContentView(R.layout.list_channel);

		// Make sure the progress bar is visible
		setProgressBarIndeterminateVisibility(true);

		w.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, category
				.getIconID());

		// Load data
		loadData();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		mnuAddChannel = menu.add(0, ADD_CHANNEL, 0,
				R.string.menu_add_channel_text).setIcon(R.drawable.ic_add);
		mnuDeleteChannel = menu.add(0, DELETE_CHANNEL, 0,
				R.string.menu_delete_channel_text)
				.setIcon(R.drawable.ic_delete);
		mnuEditChannel = menu.add(0, EDIT_CHANNEL, 0,
				R.string.menu_edit_channel_text).setIcon(R.drawable.ic_edit);
		mnuUpdateChannel = menu.add(0, UPDATE_CHANNEL, 0,
				R.string.menu_update_channel_text)
				.setIcon(R.drawable.ic_update);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		switch (item.getItemId()) {
		case ADD_CHANNEL:
			showAddChannel();
			break;
		case EDIT_CHANNEL:
			if (Store.channelModelSelected != null)
				showEditChannel();
			else {
				DialogUtils.showToastMessage(R.string.warring_no_channel_seleted);
			}
			break;
		case DELETE_CHANNEL:
			if (Store.channelModelSelected != null)
				deleteChannel();
			else {
				DialogUtils.showToastMessage(R.string.warring_no_channel_seleted);
			}
			break;
		case UPDATE_CHANNEL:
			if (Store.channelModelSelected != null){
				if (!Store.channelModelSelected.channel.isUpdating()){
					updateChannel(Store.channelModelSelected);
				} else {
					stopUpdateChannel(Store.channelModelSelected);
				}
			}
			else {
				DialogUtils.showToastMessage(R.string.warring_no_channel_seleted);
			}
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		if (!Store.hasChannelFocus) {
			mnuEditChannel.setEnabled(false);
			mnuDeleteChannel.setEnabled(false);
			mnuUpdateChannel.setEnabled(false);
		} else {
			mnuEditChannel.setEnabled(true);
			mnuDeleteChannel.setEnabled(true);
			mnuUpdateChannel.setEnabled(true);
		}
		
		if (Store.channelModelSelected != null && Store.channelModelSelected.channel != null) {
			if (Store.channelModelSelected.channel.isUpdating()) {
				mnuUpdateChannel.setTitle(R.string.menu_stop_update_channel_text);
				mnuUpdateChannel.setIcon(R.drawable.ic_stop);
			} else {
				mnuUpdateChannel.setTitle(R.string.menu_update_channel_text);
				mnuUpdateChannel.setIcon(R.drawable.ic_update);
			}
		}
		return super.onPrepareOptionsMenu(menu);
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();

		// MainController.
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);

		ItemModel model = (ItemModel) v.getTag();
		Log.i("ListItemScreen.onListItemClick", model.item.getUrl());
	}

	private void loadData() {

		adapter = new ChannelAdapter(this, channels);

		setListAdapter(adapter);
		getListView().setItemsCanFocus(true);

		new Thread() {
			public void sendMessage(int identifier) {
				Message message = new Message();
				message.what = identifier;

				// send data to update GUI
				handler.sendMessage(message);
			}

			public void run() {

				DbAdapter dbAdapter = null;
				try {
					// Open database
					dbAdapter = DbUtils.createAndOpenDbAdapter();

					channels = dbAdapter.getChannels(category);
					Log.i(TAG, "ChannelCount=" + channels.size());
				} catch (Exception ex) {
					Log.e(TAG, "loadData " + ex.toString());

					// TODO: show message dialog
				} finally {
					// Close database
					DbUtils.closeDbAdapter(dbAdapter);
				}
				sendMessage(UPDATE_CHANNEL_MESSAGE);

			}
		}.start();

		// Set default focus
		setSelection(0);
	}

	private void updateChannel(ChannelModel model) {
//		ChannelUpdater updater =  new ChannelUpdater(model.channel);
//		updater.setModel(model);
//		updater.setPriority(Thread.MIN_PRIORITY);
//		updater.setDaemon(true);
//		
//		// Add thread to list thread update
//		updaters.add(updater);
//		
//		try{
//			model.channel.setUpdating(true);
//			updater.start();
//		}catch(IllegalThreadStateException ex){
//			Log.e(TAG, ex.toString());
//		}
		model.startUpdate();
	}
	
	private void stopUpdateChannel(ChannelModel model){
//		for(ChannelUpdater updater : updaters) {
//			if (updater == null || updater.getModel() == null)
//				continue;
//			
//			if (updater.getModel().equals(model)) {
//				if (updater.isAlive()) {
//					try{
//						updater.interrupt();
//						model.channel.setUpdating(false);
//						model.endUpdate();
//					} catch(SecurityException ex){
//						Log.e(TAG, ex.toString());
//					}
//				}
//			}
//		}
		model.stopUpdate();
	}

	// show dialog add channel
	private void showAddChannel() {
		try {
			positionFocusChannel = getListView().getSelectedItemPosition();
			View viewAddChannel = getLayoutInflater().inflate(
					R.layout.add_channel, null);
			final EditText txtAddNameChannel = (EditText) viewAddChannel
					.findViewById(R.id.addChannelNameTextView);
			final EditText txtAddUrlChannel = (EditText) viewAddChannel
					.findViewById(R.id.addChannelUrlTextView);
			txtAddUrlChannel.setText("http://");
			new AlertDialog.Builder(this).setTitle(R.string.dialog_add_channel)
					.setView(viewAddChannel).setPositiveButton(
							R.string.button_dialog_ok,
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {
									String name = "";
									String url = "";
									name = txtAddNameChannel.getText()
											.toString();
									url = txtAddUrlChannel.getText().toString();
									if (name.length() == 0
											|| name.length() == 0) {
										DialogUtils.showToastMessage(R.string.warring_channel_name_url_not_null);
										return;
									} else {
										if (Store.setting.isAutoCheckUrl()) {
											if (Utils.validateUrl(url)) {
												addChannel(name, url);
											}
										}else{
											addChannel(name, url);
										}
									}
									getListView().setSelection(
											positionFocusChannel);
								}
							}).setNegativeButton(R.string.button_dialog_cancel,
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {

								}
							}).create().show();
			// getListView().getChildAt(positionFocusChannel).setFocusable(true);
		} catch (Exception ex) {
			// TODO show message dialog
			Log.e(TAG, "ShowAddChannel " + ex.toString());
		}
	}

	private void showEditChannel() {
		try {
			positionFocusChannel = getListView().getSelectedItemPosition();
			final View viewAddChannel = getLayoutInflater().inflate(
					R.layout.add_channel, null);
			final EditText txtAddname = (EditText) viewAddChannel
					.findViewById(R.id.addChannelNameTextView);
			txtAddname.setText(Store.channelModelSelected.channel.getName());
			final EditText txtAddurl = (EditText) viewAddChannel
					.findViewById(R.id.addChannelUrlTextView);
			txtAddurl.setText(Store.channelModelSelected.channel.getUrl());
			new AlertDialog.Builder(this)
					.setTitle(R.string.dialog_edit_channel).setView(
							viewAddChannel).setPositiveButton(
							R.string.button_dialog_ok,
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {
									String name;
									String url;
									name = txtAddname.getText().toString();
									url = txtAddurl.getText().toString();
									if (name.length() == 0 || url.length() == 0) {
										DialogUtils.showToastMessage(R.string.warring_channel_name_url_not_null);
									} else {
											if (Store.setting.isAutoCheckUrl()) {
												if (!Utils.validateUrl(url)) {
													try{
														DialogUtils.showDialogError(viewAddChannel.getContext(), R.string.error_to_connect_url);
													}catch(Exception ex){
														DialogUtils.showToastMessage(R.string.error_to_connect_url);
													}
													return;
												}
											}
											
											editChannel(name, url);
									}
									getListView().setSelection(
											positionFocusChannel);
								}
							}).setNegativeButton(R.string.button_dialog_cancel,
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int whichButton) {

								}
							}).create().show();
		} catch (Exception ex) {
			// TODO show message dialog
			Log.e(TAG, "showEditChannle " + ex.toString());
		}
	}

	private void addChannel(String name, String url) {
		DbAdapter dbAdapter = null;
		Channel channel = null;
		try {
			dbAdapter = DbUtils.createAndOpenDbAdapter();
			channel = new Channel();
			channel.setName(name);
			channel.setCategoryID(category.getID());
			channel.setUrl(url);
			if (!channel.validate()) {
				return;
			}
			if (dbAdapter.checkChannelExist(channel)) {
				DialogUtils.showToastMessage(R.string.warring_channel_exist);
				return;
			}
			dbAdapter.insertChannel(channel);
			loadData();
			Store.categoryModelSelected.updateNumberChannel(Store.categoryModelSelected.category);
		} catch (Exception ex) {
			// TODO show message dialog
			Log.i(TAG, ex.toString());
		} finally {
			if (dbAdapter != null) {
				DbUtils.closeDbAdapter(dbAdapter);
			}
		}
	}

	private void editChannel(String name, String url) {
		DbAdapter dbAdapter = null;
		Channel channel = Store.channelModelSelected.channel;
		channel.setName(name);
		channel.setUrl(url);
		try {
			dbAdapter = DbUtils.createAndOpenDbAdapter();
			if (dbAdapter.checkChannelExist(channel)) {
				DialogUtils.showToastMessage(R.string.warring_channel_exist);
				return;
			}
			Log.i(TAG,"id channel = "+channel.getID());
			dbAdapter.updateChannel(channel);
			Store.channelModelSelected.channel.setName(name);
			Store.channelModelSelected.channel.setUrl(url);
			loadData() 	;
			Store.categoryModelSelected.updateNumberChannel(Store.categoryModelSelected.category);
		} catch (Exception ex) {
			// TODO show message dialog
			Log.e(TAG, ex.toString());
		} finally {
			if (dbAdapter != null) {
				DbUtils.closeDbAdapter(dbAdapter);
			}
		}
		// getListView().setSelection(positionFocusChannel);
	}

	private void deleteChannel() {
		positionFocusChannel = getListView().getSelectedItemPosition();
		TextView txtWarringDeleteCategory = new TextView(getBaseContext());
		txtWarringDeleteCategory.setText(getResources().getString(
				R.string.dialog_delete_channel_textview)
				+ " \"" + Store.channelModelSelected.channel.getName()+"\"");
		new AlertDialog.Builder(this).setTitle(
				R.string.dialog_delete_channel_title).setView(
				txtWarringDeleteCategory).setPositiveButton(
				R.string.button_dialog_ok,
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
						DbAdapter dbAdapter = null;
						Channel channel = null;
						try {
							dbAdapter = DbUtils.createAndOpenDbAdapter();
							channel = new Channel();
							channel.setID(Store.channelModelSelected.channel
									.getID());
							dbAdapter.deleteChannel(channel);
							
							// Delete logo's channel
							String logoFile = Constants.CHANNEL_LOGO_PREFIX + channel.getID();
							FileUtils.deleteImage(logoFile);
							loadData();
							if(positionFocusChannel == 0){
								positionFocusChannel++;
							} else if (positionFocusChannel > getListView()
									.getCount())
								positionFocusChannel = getListView().getCount();
							getListView().setSelection(--positionFocusChannel);
								positionFocusChannel = getListView().getCount();
							Store.categoryModelSelected.updateNumberChannel(Store.categoryModelSelected.category);
						} catch (Exception ex) {
							// TODO show message dialog
							Log.e(TAG, ex.toString());
						} finally {
							if (dbAdapter != null) {
								DbUtils.closeDbAdapter(dbAdapter);
							}
						}
					}
				}).setNegativeButton(R.string.button_dialog_cancel,
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {

					}
				}).create().show();
	}
}
